require("Scripts/Common/Class")
require("Scripts/Common/Utility")

LoopGroup = Class()

function LoopGroup:Ctor()
	self._total_count = 0
	self._complate_count = 0
	self._loop_updaters = {}
	self._complate_updaters = {}
end

function LoopGroup:AddUpdater(updater)
	if updater == nil then return end
	if self._complate_updaters[updater] or self._loop_updaters[updater] then return end
	self._loop_updaters[updater] = updater
	self._total_count = self._total_count + 1
end

function LoopGroup:RemoveUpdater(updater)
	if self._loop_updaters[updater] then
		self._loop_updaters[updater] = nil
		self._total_count = self._total_count - 1
		return
	end
	if self._complate_updaters[updater] then
		self._complate_updaters[updater] = nil
		self._total_count = self._total_count - 1
		self._complate_count = self._complate_count - 1
	end
end

function LoopGroup:Reset()
	self._complate_count = 0
	for k, v in pairs(self._complate_updaters) do
		self._loop_updaters[v] = v
		v:Reset()
	end
end

function LoopGroup:SetTime(time)
	if self._total_count == 0 then return time end
	local min_time = 10000000000
	local total_updater = {}
	for k, v in pairs(self._loop_updaters) do
		total_updater[k] = v
	end
	for k, v in pairs(self._complate_updaters) do
		total_updater[k] = v
	end
	self._loop_updaters = {}
	self._complate_updaters = {}
	self._complate_count = 0
	for k, v in pairs(total_updater) do
		local remain_time = v:SetTime(time)
		if remain_time == 0 then
			self._complate_updaters[v] = v
			self._complate_count = self._complate_count + 1
		else
			self._loop_updaters[v] = v
		end
		if min_time > remain_time then min_time = remain_time end
	end
	return min_time
end

function LoopGroup:IsCompleted()
	return self._complate_count >= self._total_count
end

function LoopGroup:Update(frame_time)
	if self._complate_count >= self._total_count then return end
	local remove_list = {}
	for updater_k, updater_v in pairs(self._loop_updaters) do
		updater_v:Update(frame_time)
		if updater_v:IsCompleted() then
			remove_list[updater_v] = updater_v
		end
	end
	for k, v in pairs(remove_list) do
		self._loop_updaters[v] = nil
		self._complate_updaters[v] = v
		self._complate_count = self._complate_count + 1
	end
end
